package com.xgst.bmg.service;

import com.xgst.bmg.utils.CaptureScreenUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * @BelongsProject: screen-win
 * @BelongsPackage: com.xgst.bmg.service
 * @Author: xgstjs-11
 * @CreateTime: 2021-02-22 09:44:38
 * @Description: 异步业务
 */
@Component
public class AsyncSercive {
    private static final Logger log = LoggerFactory.getLogger(AsyncSercive.class);
    private static Charset charset = Charset.forName("UTF-8");

    //SSE发射器
    private static SseEmitter emitter = null;
    //启动停止
    private static boolean bl = false;
    //BufferedImage队列
    private static HashMap<Long,BufferedImage> bufferedImageHashMap = new HashMap();
    //base64队列,TreeMap自动升序排列
    private static TreeMap<Long,String> base64HashMap = new TreeMap();

    public AsyncSercive() {
    }

    public void setEmitter(SseEmitter emitter) {
        this.emitter = emitter;
    }

    public void setBl(boolean bl) {
        this.bl = bl;
    }

    @Async
    public void startBase64(){
        Long firstKey = 0L;
        BufferedImage firstValue = null;
        while (bl) {
            try {
                if (bufferedImageHashMap.size() > 0) {
                    for (Map.Entry<Long, BufferedImage> entry : bufferedImageHashMap.entrySet()) {
                        firstKey = entry.getKey();
                        if (firstKey != 0L && firstKey != null) {
                            firstValue = entry.getValue();
                            bufferedImageHashMap.remove(firstKey);
                            break;
                        }
                    }
                    if (firstKey != 0L && firstValue != null) {
                        bufferedImageAsBase64(firstKey, firstValue);
                    }
                }
            } catch(Exception e){
                e.printStackTrace();
            }
        }
    }

    @Async
    public void startCapture(){
        //捕获屏幕
        while (bl){
            try {
                captureBufferedImage();
                Thread.sleep(40);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Async
    public void startEmitter(){
        //发射base64
        Long firstKey = null;
        String firstValue = null;
        while (bl){
            if(base64HashMap.size()>0) {
                base64Emitter(firstKey, firstValue);
            }
            try {
                Thread.sleep(40);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Async("captureBufferedImage")
    public void captureBufferedImage(){
        BufferedImage screenCapture = CaptureScreenUtils.captureBufferedImage();
        bufferedImageHashMap.put(System.currentTimeMillis(),screenCapture);
    }

    @Async("bufferedImageAsBase64")
    public void bufferedImageAsBase64(Long firstKey, BufferedImage bufferedImage){
        Long firstKeyCurrent = 0L;
        if(base64HashMap.size()>0){
            for (Map.Entry<Long,String> entry : base64HashMap.entrySet()) {
                firstKeyCurrent = entry.getKey();
                if (firstKey != 0L && firstKey != null) {
                    break;
                }
            }
        }
        if (firstKey > firstKeyCurrent && firstKey != 0L && bufferedImage != null){
            String a = CaptureScreenUtils.bufferedImageAsBase64(bufferedImage);
            base64HashMap.put(firstKey, a);
        }
    }

    @Async("base64Emitter")
    public void base64Emitter(Long firstKey,String firstValue){
        try {
            for (Map.Entry<Long,String> entry : base64HashMap.entrySet()) {
                firstKey = entry.getKey();
                firstValue = entry.getValue();
                if(firstValue != null){
                    emitter.send(SseEmitter.event().reconnectTime(1).data(firstValue));
//                    log.info("--send  "+firstKey.toString());
                }
                base64HashMap.remove(firstKey);
                break;
          }
        } catch (IOException e) {
            e.printStackTrace();
            bl=false;
        }
    }

}
